package com.lyb.ui.controller;

import com.lyb.constant.MemoryConstant;
import com.lyb.constant.SystemConstant;
import com.lyb.hardware.AlpacaMainBoard;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.util.Duration;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

/**
 * 内存页面的控制器
 *
 * @author Dayun Mr.Alpaca
 * @version 1.4.0
 */
public class MemoryController implements Initializable {
    @FXML
    public Label sumSizeSign;
    @FXML
    public Label sumSignLabel;
    @FXML
    public Label usedSizeSign;
    @FXML
    public Label usedSizeLabel;
    @FXML
    public Label emptySizeSign;
    @FXML
    public Label emptySignLabel;
    @FXML
    private GridPane gridPane;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        /* 获取操作对象 */
        ObservableList<Node> textAreas = gridPane.getChildren();
        AlpacaMainBoard mainBoard = SystemConstant.MAIN_BOARD;
        List<Alert> alertList = new ArrayList<>();
        sumSignLabel.setText(MemoryConstant.USER_AREA_SIZE + " 字节");

        /* 给内存块添加弹窗 */
        for (int i = 0; i < MemoryConstant.USER_AREA_LINE_NUM; i++) {
            Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "", new ButtonType("取消", ButtonBar.ButtonData.NO),
                    new ButtonType("确定", ButtonBar.ButtonData.YES));
            alert.setTitle("内存行内容");
            alertList.add(alert);
        }
        /* 鼠标双击内存块弹窗 */
        for (int i = 0; i < MemoryConstant.USER_AREA_LINE_NUM; i++) {
            Node node = textAreas.get(i);
            int finalI = i;
            node.setOnMouseClicked(event -> {
                alertList.get(finalI).showAndWait();
            });
        }

        /* 获取各组件动画事件 */
        KeyFrame spaceFrame = getSpaceFrame(textAreas, alertList, mainBoard);
        KeyFrame usedFrame = getUsedSizeFrame(mainBoard);
        KeyFrame emptyFrame = getEmptySizeFrame(mainBoard);

        /* 添加动画事件到时间线 */
        Timeline timeline = new Timeline();
        timeline.getKeyFrames().addAll(spaceFrame, usedFrame, emptyFrame);
        timeline.setCycleCount(Timeline.INDEFINITE);
        timeline.setAutoReverse(true);
        timeline.play();
    }

    /**
     * 获取内存块组件的动画
     *
     * @param textAreas 内存块
     * @param alertList 弹窗事件
     * @param mainBoard 主板
     * @return 动画
     */
    private KeyFrame getSpaceFrame(ObservableList<Node> textAreas, List<Alert> alertList, AlpacaMainBoard mainBoard) {
        return new KeyFrame(Duration.millis(1000), event -> {
            byte[] mat = mainBoard.getMatFromMemory();
            for (int i = 0; i < MemoryConstant.USER_AREA_LINE_NUM; i++) {
                Rectangle rectangle = (Rectangle) textAreas.get(i);
                rectangle.setFill(mat[i] == 0 ? Color.GREEN : Color.BLUE);
                alertList.get(i).setHeaderText(mainBoard.readContentFromMemory(i));
            }
        });
    }

    /**
     * 获取已使用空间组件的动画
     *
     * @param mainBoard 主板
     * @return 动画
     */
    private KeyFrame getUsedSizeFrame(AlpacaMainBoard mainBoard) {
        return new KeyFrame(Duration.millis(1000), event -> {
            usedSizeLabel.setText((MemoryConstant.USER_AREA_SIZE - mainBoard.getEmptySizeFromMemory()) + " 字节");
        });
    }

    /**
     * 获取空闲空间组件的动画
     *
     * @param mainBoard 主板
     * @return 动画
     */
    private KeyFrame getEmptySizeFrame(AlpacaMainBoard mainBoard) {
        return new KeyFrame(Duration.millis(1000), event -> {
            emptySignLabel.setText(mainBoard.getEmptySizeFromMemory() + " 字节");
        });
    }
}
